import json
import random
from pathlib import Path
from dataclasses import dataclass
from typing import NamedTuple,Dict,Literal,Tuple,cast



class PunchProfile(NamedTuple):
    choice: int
    threshold: int
    hit_damage: int
    block_damage: int

    pre_msg: str
    hit_msg: str
    blocked_msg: str

    knockout_possible: bool = False


    def is_hit(self):
        return random.randint(1,self.choices) <= self.threshold
@dataclass
class Player:
        name: str
        best: int
        weakness: int
        HP: int
        #可以通过is_computer判断是玩家还是电脑
        is_computer: bool
        punch_profiles: Dict[Literal[1,2,3,4],PunchProfile]
        damage: int = 0
        score: int = 0
        knockedout:bool=False

        def get_punch_choice(self) -> Literal [1,2,3,4]:
            #生成电脑的拳法通过随机数
            if self.is_computer:
                return  random.randint(1,4)
            punch = -1
        #通过while死循环要求玩家必须选择1-4中一个数字
            while punch not in [1,2,3,4,]:
                print(f"={self.name}的招式是?")
                #缺个是不是数字的判断
                punch = int (input())
                return punch
#击倒阈值
KNOCKOUT_THRESHOLD =40
#击晕信息
KNOCKOUT_COLD = "{loser}被击晕了无法正常比赛，胜利属于{winner}"

#获取选手弱点信息
def get_vulnerability():
    print("他的弱点是?")
    #对于数字的判断
    return int(input())
#获取电脑弱点信息
def get_opponent_stats() -> Tuple[int,int]:
    opponent_best = 0
    opponent_weakness = 0
    while opponent_best==opponent_weakness:
        opponent_best = random.randint(1,4)
        opponent_weakness = random.randint(1,4)

        return opponent_best,opponent_weakness

    #获取招式基本信息
def read_punch_profiles(filepath: Path):
        with open(filepath,encoding='utf-8') as f:
            punch_profiles_dict = json.load(f)
        return  {
            cast(Literal[1,2,3,4],int(key)):PunchProfile(**value)
            for key,value in punch_profiles_dict.items()
        }

def main() ->None:
    print("拳击游戏")
    print("desgin by zct")
    print("由zct设计创建")
    print("202312060341")

    print("你的对手名字为：")
    player_name = input()
    opponent_name=input()

    print("不同的出拳策略 1.摆拳 2.平勾拳 3.上钩拳 4.刺拳 ")
    print("你擅长的招式是？")
    player_beat = int(input())
    player_weakness = get_vulnerability()
    player=Player(
        name = player_name,
        best = player_beat,
        weakness = player_weakness,
        is_computer = False,
        punch_profiles=read_punch_profiles(
            Path(__file__).parent/"player-profile.json"
        ),
    )

    opponent_best,opponent_weakness=get_opponent_stats()
    opponent = Player(
        name=opponent_name,
        best=opponent_best,
        weakness=opponent_weakness,
        is_computer=True,
        punch_profiles=read_punch_profiles(
            Path(__file__).parent /"opponent-profile.json"
        ),
    )
    #做一次判断看能不能读取对应文件数据
    #print(player)
    #print(opponent)
    print("比赛正式开始，请做好准备！")

    for round_number in (1,2,3):
        if player.knockout or opponent.knockout:
            break
        play_round(round_number,player,opponent)

    if player.knockout:
        print(KNOCKOUT_COLD.format(loser=player.name,winner=opponent.name))
    elif opponent.knockout:
        print(KNOCKOUT_COLD.format(loser=opponent.name,winner=player.name))
    elif opponent.score > player.score:
        print(f"{opponent.name}打败了{player.name}")
    else:
        print(f"{player.name}打败了{opponent.name}")

    print("\n\n比赛结束")
    print("感谢游玩")

#生成1-10随机数，大于5则为对面回合
def is_opponents_turn() ->bool:
    return random.randint(1,10)>5

def play_round(round_number: int, player: Player, opponent:Player) ->None:
    print(f"第{round_number}轮次。\n开始.....\n")
    #三局两胜的规则，一方>=2，游戏结束
    if opponent.score>=2 or player.score>=2:
        return

    for _action in range(7):
        if is_opponents_turn():
            punch = opponent.get_punch_choice()
            active=opponent
            passive = player
            opponent_turn = True
        else:
            punch = player.get_punch_choice()
            active = player
            passive = opponent
            opponents_turn = False

            punch_profile = active.punch_profiles[punch]

        #
            if punch == active.best:
                active.damage = active.damage+2

                print(punch_profile.pre_msg.format(opponent=opponent,player=player))

            #如果对手不擅长这个招数，那他将总是被击中
            if passive.weakness == punch or punch_profile.is_hit():
                print(punch_profile.hit_msg.format(opponent=opponent,player=player))
                if punch_profile.knockout_possible and active.damage > KNOCKOUT_THRESHOLD:
                     if opponents_turn and opponent.damage>KNOCKOUT_THRESHOLD:
                        player.knockedout=True
                        break
                     elif opponents_turn == False and player.damage>KNOCKOUT_THRESHOLD:
                        opponent.knockedout=True
                        break
                # 如果不存在击倒可能性则记录伤害
                if opponent_turn == True:
                    opponent.damage = opponent.damage + punch_profile.hit_damage
                else:
                    player.damage += punch_profile.hit_damage

            else:...

            if player.knockedout or opponent.knockedout:
                break

    #这里的分数用伤害统计，不太合理并且每一局伤害会累计到下一场
    if player.damage > opponent.damage:
        print(f"{player.name}获得了第{round_number}场胜利")
    else:
        print(f"{opponent.name}获得了第{round_number}场胜利")

if __name__ == "__main__":
    main()